package top.misspro.valheimadminsocket.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import lombok.extern.slf4j.Slf4j;
import top.misspro.valheimadminsocket.handler.TextMessageHandle;

import java.net.InetSocketAddress;

/**
 * @author Evan
 */
@Slf4j
public class NettyServer {

    public void start(InetSocketAddress socketAddress) {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup(4);
        EventExecutorGroup executorGroup = new DefaultEventExecutorGroup(8);

        //启动器初始化
        ServerBootstrap bootstrap = new ServerBootstrap()
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {

                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        //web socket http解码支持
                        pipeline.addLast(new HttpServerCodec());
                        pipeline.addLast(new ChunkedWriteHandler());

                        pipeline.addLast(new HttpObjectAggregator(65536));
                        pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
                        pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));

                        pipeline.addLast(new IdleStateHandler(4, 8, 3600));

                        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

                        pipeline.addLast(executorGroup, new TextMessageHandle());
                    }
                })
                .localAddress(socketAddress)
                .option(ChannelOption.SO_BACKLOG, 1024)
                .childOption(ChannelOption.SO_KEEPALIVE, true);

        log.info("socket 服务器配置初始化完成......");

        //启动
        try {
            //同步启动
            ChannelFuture future = bootstrap.bind(socketAddress).sync();
            log.info("socket 服务器启动完成！");
            future.channel().closeFuture().sync();
            log.info("socker 服务器已关闭！");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            log.info("开始释放线程池");
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
            executorGroup.shutdownGracefully();
            log.info("线程池释放完成！");
        }


    }
}
